package ru.spbu.math.android.cbrf.dataprovider.yandex;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.content.res.Resources;
import android.util.Log;

import ru.spbu.math.android.cbrf.R;
import ru.spbu.math.android.cbrf.model.Category;
import ru.spbu.math.android.cbrf.model.RateType;
import ru.spbu.math.android.cbrf.model.StockItem;

/**
 * Class for keeping data about all available RateTypes for Yandex
 *
 */

class RateTypeStore {
	
	private final static String LOG_TAG = "Yandex.RateTypeStore";
	
	private static Resources resources;
	private static RateTypeStore instance;

	public ArrayList<RateType> rateList;
	private ArrayList<RateType> oilList;
	private ArrayList<RateType> metalList;
	private ArrayList<RateType> crossList;
	private ArrayList<RateType> marketList;
	private ArrayList<RateType> stockList;
	
	private static String oilCategory;
	private static String metalCategory;
	private static String crossCategory;
	private static String marketCategory;
	private static String stockCategory;
	

	public static RateTypeStore Instance(Resources res) {
		if (instance == null) {
			resources = res;
			instance = new RateTypeStore(resources);
		}
		return instance;
	}

	private RateTypeStore(Resources resources) {
		
		rateList = new ArrayList<RateType>();
		oilList = new ArrayList<RateType>();
		metalList = new ArrayList<RateType>();
		crossList = new ArrayList<RateType>();
		marketList = new ArrayList<RateType>();
		stockList = new ArrayList<RateType>();
		
		oilCategory = resources.getString(R.string.Yandex_Oil);
		metalCategory = resources.getString(R.string.Yandex_Metal);
		crossCategory = resources.getString(R.string.Yandex_Cross);
		marketCategory = resources.getString(R.string.Yandex_Market);
		stockCategory = resources.getString(R.string.Yandex_Stock);
         
		try {
			RateTypeSaxHandler handler = new RateTypeSaxHandler();
			handler.setResources(resources);
	        SAXParserFactory factory = SAXParserFactory.newInstance();
	        SAXParser parser = factory.newSAXParser();
	        InputSource courseXml = new InputSource(resources.openRawResource(R.raw.rate_type_yandex));
			parser.parse(courseXml, handler);
			oilList = (ArrayList<RateType>) handler.getOil();
			metalList = (ArrayList<RateType>) handler.getMetal();
			crossList = (ArrayList<RateType>) handler.getCross();
			marketList = (ArrayList<RateType>) handler.getMarket();
			stockList = (ArrayList<RateType>) handler.getStock();
			
			Log.d(LOG_TAG, "was parsed");
			Log.d(LOG_TAG, "currencyList size: " + oilList.size());
			Log.d(LOG_TAG, "metalList size: " + metalList.size());
			for(RateType rateType : oilList){
				Log.d(LOG_TAG, "Currency. id: " + rateType.getId());
				rateList.add(rateType);
			}
			
			for(RateType rateType : metalList){
				Log.d(LOG_TAG, "Metal. id: " + rateType.getId());
				rateList.add(rateType);
			}
			
			for(RateType rateType : crossList){
				Log.d(LOG_TAG, "Cross-Rate. id: " + rateType.getId());
				rateList.add(rateType);
			}
			
			for(RateType rateType : marketList){
				Log.d(LOG_TAG, "Stock market. id: " + rateType.getId());
				rateList.add(rateType);
			}
			
			for(RateType rateType : stockList){
				Log.d(LOG_TAG, "Stock. id: " + rateType.getId());
				rateList.add(rateType);
			}
			
		} catch (ParserConfigurationException e) {
			Log.e(LOG_TAG, "ParserConfigurationException");
		} catch (SAXException e) {
			Log.e(LOG_TAG, "SAXException");
		} catch (IOException e) {
			Log.e(LOG_TAG, "IOException");
		}
	}
	
	/**
	 * @return all available categories
	 */
	public List<Category> getCategories() {
		ArrayList<Category> categories = new ArrayList<Category>();
		categories.add(new Category(oilCategory));
		categories.add(new Category(metalCategory));
		categories.add(new Category(crossCategory));
		categories.add(new Category(marketCategory));
		categories.add(new Category(stockCategory));
		return categories;
	}
	
	
	@SuppressWarnings("unchecked")
	public List<RateType> getRateTypesByCategory(Category category) {
		
		// TODO change it!!
		if (category.getName().equals(oilCategory)) {
			return (List<RateType>) oilList.clone();
		}
		else if (category.getName().equals(metalCategory)) {
			return (List<RateType>) metalList.clone();
		}
		else if (category.getName().equals(crossCategory)) {
			return (List<RateType>) crossList.clone();
		}
		else if (category.getName().equals(marketCategory)) {
			return (List<RateType>) marketList.clone();
		}
		else if (category.getName().equals(stockCategory)) {
			return (List<RateType>) stockList.clone();
		}
		
		return null;
	}
	
	/**
	 * Gets RateType by id
	 * @param id
	 * @return RateType
	 */
	public RateType findRateTypeById(String id){
		for(RateType rate: instance.rateList){
			if(rate.getId().equals(id)){
				return rate;
			}
		}
		return null;
	}
	
	/**
	 * Gets RateType by source
	 * @param source
	 * @return RateType
	 */
	public RateType findRateTypeBySource(StockItem source){
		RateTypeStore instance = RateTypeStore.Instance(resources);
		for(RateType rate: instance.rateList){
			if(rate.getSource().getCode().equals(source.getCode())){
				return rate;
			}
		}
		return null;
	}
}

